package executives.thread_managers;

import java.util.concurrent.BlockingQueue;

/**
 * Consumer represents a target for a thread which takes tasks from
 * SpikeProducer's task queue (blocking queue) and runs them to their 
 * conclusion. Consumer continues to do this even if the tasks queue is empty
 * and awaits more tasks to take until SpikeProducer sends and exhaused signal
 * indicating that there will never be more tasks in the task queue to be 
 * consumed.
 * 
 * @author zach
 *
 */
public class Consumer implements Runnable{

	/** The task queue of available runnables. */
	private final BlockingQueue<Runnable> queue;
	
	/** 
	 * A reference to the producer which organizes and produces new tasks
	 * for the task queue. Consumer checks the producer each cycle to
	 * determine if any tasks remain.
	 */
	private SpikeProducer producer;
	
	/**
	 * Construct the consumer.
	 * @param queue the queue of available runnable tasks
	 * @param producer the object which produces new tasks when the task queue
	 * is empty. Consumer stops when the producer indicates that it is
	 * exhausted and no more tasks remain.
	 */
	public Consumer (BlockingQueue<Runnable> queue,
			SpikeProducer producer) {
		this.queue = queue;
		this.producer = producer;
	}
	
	/**
	 * Run the consumer. Consists of running any available tasks in the queue
	 * and checking the producer to ensure that more tasks may be produced even
	 * if the queue is, for the time being, empty.
	 */
	@Override
	public void run() {
		
		try {
			//Run until the producer indicates there will never be any
			//more tasks
			while(!producer.isExhausted()) {
					
					Runnable r = queue.take();
					if(r != null){
						r.run();
						producer.getSyncLatch().countDown();
					}
					
			}
			
			return;
			
		} catch (InterruptedException e) {
		}
		
	}

}
